package ${groupId}.${artifactIdProjectPackageName}.common.result;


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.StringUtils;


import java.io.Serializable;

/**
 * 统一返回的前段实体类
 * @param <T>
 */
@ApiModel("统一返回的前段实体类")
public class ResultSet<T> implements Serializable {

    private static final long serialVersionUID = 1856063848370313985L;

    /**
     * 成功结果
     * 错误码默认使用 系统默认SUCCESS
     */
    public static final ResultSet SUCCESS = new ResultSet(SystemErrorCode.SUCCESS.getDcode(),SystemErrorCode.SUCCESS.getCode(), SystemErrorCode.SUCCESS.getMsg());
    public static final ResultSet FAIL = new ResultSet(SystemErrorCode.ERROR.getDcode(),SystemErrorCode.ERROR.getCode(), SystemErrorCode.ERROR.getMsg());

    private ResultSet() {}

    /**
     * 创建一个成功可带成功消息的返回结果
     * @param msg 消息
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderSuccess(String msg){
        return new ResultSet<>(SUCCESS.dcode, SUCCESS.code, msg);
    }

    /**
     * 创建一个成功的返回结果
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderSuccess() {
        return builderSuccess(SUCCESS.getMsg());
    }

    /**
     * 创建一个成功带数据（非String类型）的返回结果
     * @param data 数据对象
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderSuccess(E data) {
        ResultSet<E> resultSet = builderSuccess();
        resultSet.setData(data);
        return resultSet;
    }

    /**
     * 创建一个成功可带消息、数据的返回结果
     * @param msg 消息
     * @param data 数据对象
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderSuccess(String msg,E data) {
        ResultSet<E> resultSet = builderSuccess(msg);
        resultSet.setData(data);
        return resultSet;
    }

    /**
     * 通过错误码创建一个返回结果
     * 默认使用错误码的消息提示
     * @param errorCode 错误码对象
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderFail(ErrorCode errorCode) {
        return builderFail(errorCode.getDcode(),errorCode.getCode(), errorCode.getMsg(), null);
    }

    /**
     * 通过错误码创建一个返回结果
     * 使用参数msg 做为消息提示
     * @param errorCode 错误码对象
     * @param msg 消息消息
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderFail(ErrorCode errorCode, String msg) {
        msg = StringUtils.isNotBlank(msg)?msg : errorCode.getMsg();
        return builderFail(errorCode.getDcode(),errorCode.getCode(), msg, null);
    }

    /**
     * 通过错误码创建一个返回结果
     * 使用参数msg 做为消息提示
     * 使用参数data 添加错误附加数据对象
     * @param errorCode 错误码对象
     * @param msg 消息消息
     * @param data 附加数据对象
     * @return 返回一个结果集
     */
    public static <E> ResultSet<E> builderFail(ErrorCode errorCode, String msg, E data) {
        msg = StringUtils.isNotBlank(msg)?msg : errorCode.getMsg();
        return builderFail(errorCode.getDcode(),errorCode.getCode(), msg, data);
    }

    /**
     * 通过错误码创建一个返回结果
     * 使用参数dcode 做为后端服务调用错误码
     * 使用参数msg 做为消息提示
     * 使用参数data 添加错误附加数据对象
     * @param dcode 后端错误
     * @param code 前段错误码
     * @param msg 消息消息
     * @param data 附加数据对象
     * @return 返回一个结果集
     */
    private static <E> ResultSet<E> builderFail(String dcode,int code, String msg,E data) {
        ResultSet<E> resultSet = new ResultSet<>(dcode,code,msg);
        resultSet.setData(data);
        return resultSet;
    }


    @ApiModelProperty("前段使用错误码")
    private int code = 0;
    @ApiModelProperty("后端错误码")
    private String dcode = "";
    @ApiModelProperty("错误消息")
    private String msg;
    @ApiModelProperty("错误消息")
    private boolean success;
    @ApiModelProperty("返回数据")
    private T data;

    public ResultSet(String dcode,int code,String msg) {
        this.dcode = dcode;
        this.code = code;
        this.msg = msg;
        this.success = String.valueOf(code).startsWith("2");
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getDcode() {
        return dcode;
    }

    public void setDcode(String dcode) {
        this.dcode = dcode;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    @Override
    public String toString() {
        return "ResultSet{" +
                "code=" + code +
                ", dcode='" + dcode + '\'' +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }

}
